-- Lua Battle System - 统一错误类型
-- 定义系统中使用的所有错误类型和错误信息格式化

local Errors = {
    -- 错误类型枚举
    types = {
        -- 系统错误
        SYSTEM_ERROR = "SYSTEM_ERROR",
        INIT_ERROR = "INIT_ERROR",
        CONFIG_ERROR = "CONFIG_ERROR",
        MEMORY_ERROR = "MEMORY_ERROR",
        FILE_ERROR = "FILE_ERROR",
        NETWORK_ERROR = "NETWORK_ERROR",
        TIMEOUT_ERROR = "TIMEOUT_ERROR",

        -- 战斗错误
        BATTLE_ERROR = "BATTLE_ERROR",
        INVALID_BATTLE_ID = "INVALID_BATTLE_ID",
        BATTLE_NOT_IN_PROGRESS = "BATTLE_NOT_IN_PROGRESS",
        BATTLE_FINISHED = "BATTLE_FINISHED",
        INVALID_TURN = "INVALID_TURN",
        TURN_OUT_OF_ORDER = "TURN_OUT_OF_ORDER",

        -- 角色错误
        CHARACTER_ERROR = "CHARACTER_ERROR",
        INVALID_CHARACTER = "INVALID_CHARACTER",
        CHARACTER_DEAD = "CHARACTER_DEAD",
        CHARACTER_NOT_IN_BATTLE = "CHARACTER_NOT_IN_BATTLE",
        INSUFFICIENT_RESOURCES = "INSUFFICIENT_RESOURCES",
        CHARACTER_FULL = "CHARACTER_FULL",
        CHARACTER_CANNOT_ACT = "CHARACTER_CANNOT_ACT",

        -- 技能错误
        SKILL_ERROR = "SKILL_ERROR",
        INVALID_SKILL = "INVALID_SKILL",
        SKILL_NOT_LEARNED = "SKILL_NOT_LEARNED",
        SKILL_COOLDOWN = "SKILL_COOLDOWN",
        INVALID_TARGET = "INVALID_TARGET",
        SKILL_INTERRUPTED = "SKILL_INTERRUPTED",
        SKILL_FAILED = "SKILL_FAILED",
        SKILL_OUT_OF_RANGE = "SKILL_OUT_OF_RANGE",

        -- 物品错误
        ITEM_ERROR = "ITEM_ERROR",
        INVALID_ITEM = "INVALID_ITEM",
        ITEM_NOT_OWNED = "ITEM_NOT_OWNED",
        ITEM_NOT_USABLE = "ITEM_NOT_USABLE",
        INSUFFICIENT_ITEMS = "INSUFFICIENT_ITEMS",
        ITEM_EXPIRED = "ITEM_EXPIRED",

        -- AI错误
        AI_ERROR = "AI_ERROR",
        DECISION_ERROR = "DECISION_ERROR",
        AI_TIMEOUT = "AI_TIMEOUT",
        INVALID_AI_STATE = "INVALID_AI_STATE",
        AI_BLACKLISTED_ACTION = "AI_BLACKLISTED_ACTION",

        -- 数据错误
        DATA_ERROR = "DATA_ERROR",
        DATA_CORRUPTION = "DATA_CORRUPTION",
        DATA_VALIDATION_FAILED = "DATA_VALIDATION_FAILED",
        INVALID_PARAMETER = "INVALID_PARAMETER",
        TYPE_MISMATCH = "TYPE_MISMATCH",

        -- 性能错误
        PERFORMANCE_ERROR = "PERFORMANCE_ERROR",
        PERFORMANCE_DEGRADED = "PERFORMANCE_DEGRADED",
        RESOURCE_EXHAUSTED = "RESOURCE_EXHAUSTED",
        OVERLOAD = "OVERLOAD"
    },
    
    -- 错误信息模板
    messages = {
        -- 系统错误
        SYSTEM_ERROR = "系统错误: %s",
        INIT_ERROR = "初始化错误: %s",
        CONFIG_ERROR = "配置错误: %s",
        MEMORY_ERROR = "内存错误: %s",
        FILE_ERROR = "文件错误: %s",
        NETWORK_ERROR = "网络错误: %s",
        TIMEOUT_ERROR = "超时错误: %s",

        -- 战斗错误
        INVALID_BATTLE_ID = "无效的战斗ID: %s",
        BATTLE_NOT_IN_PROGRESS = "战斗未在进行中: %s",
        BATTLE_FINISHED = "战斗已结束: %s",
        INVALID_TURN = "无效的回合: %s",
        TURN_OUT_OF_ORDER = "回合顺序错误: %s",

        -- 角色错误
        INVALID_CHARACTER = "无效的角色: %s",
        CHARACTER_DEAD = "角色已阵亡: %s",
        CHARACTER_NOT_IN_BATTLE = "角色不在战斗中: %s",
        INSUFFICIENT_RESOURCES = "资源不足: %s",
        CHARACTER_FULL = "角色已满: %s",
        CHARACTER_CANNOT_ACT = "角色无法行动: %s",

        -- 技能错误
        INVALID_SKILL = "无效的技能: %s",
        SKILL_NOT_LEARNED = "角色未学习该技能: %s",
        SKILL_COOLDOWN = "技能冷却中: %s",
        INVALID_TARGET = "无效的目标: %s",
        SKILL_INTERRUPTED = "技能被中断: %s",
        SKILL_FAILED = "技能执行失败: %s",
        SKILL_OUT_OF_RANGE = "目标超出技能范围: %s",

        -- 物品错误
        INVALID_ITEM = "无效的物品: %s",
        ITEM_NOT_OWNED = "角色未拥有该物品: %s",
        ITEM_NOT_USABLE = "物品不可使用: %s",
        INSUFFICIENT_ITEMS = "物品数量不足: %s",
        ITEM_EXPIRED = "物品已过期: %s",

        -- AI错误
        DECISION_ERROR = "AI决策错误: %s",
        AI_TIMEOUT = "AI决策超时: %s",
        INVALID_AI_STATE = "无效的AI状态: %s",
        AI_BLACKLISTED_ACTION = "AI动作被黑名单阻止: %s",

        -- 数据错误
        DATA_ERROR = "数据错误: %s",
        DATA_CORRUPTION = "数据损坏: %s",
        DATA_VALIDATION_FAILED = "数据验证失败: %s",
        INVALID_PARAMETER = "无效的参数: %s",
        TYPE_MISMATCH = "类型不匹配: %s",

        -- 性能错误
        PERFORMANCE_ERROR = "性能错误: %s",
        PERFORMANCE_DEGRADED = "性能下降: %s",
        RESOURCE_EXHAUSTED = "资源耗尽: %s",
        OVERLOAD = "系统过载: %s"
    }
}

-- 错误构造函数
function Errors:new(error_type, message, details)
    local error_obj = {
        type = error_type,
        message = message,
        details = details,
        timestamp = os.time()
    }
    
    return error_obj
end

-- 创建错误对象
-- @param error_type 错误类型
-- @param message 错误信息（可选）
-- @param details 错误详情（可选）
function Errors:create(error_type, message, details)
    local template = self.messages[error_type] or self.messages.SYSTEM_ERROR
    local formatted_message
    
    if message then
        formatted_message = string.format(template, message)
    else
        formatted_message = template:gsub("%%s", ""):gsub("^%s*", ""):gsub("%s*$", "")
    end
    
    return self:new(error_type, formatted_message, details)
end

-- 格式化错误信息
-- @param error_obj 错误对象
function Errors:format(error_obj)
    if type(error_obj) == "string" then
        return error_obj
    end
    
    local formatted = string.format("[%s] %s", error_obj.type, error_obj.message)
    
    if error_obj.details then
        formatted = formatted .. " | 详情: " .. tostring(error_obj.details)
    end
    
    return formatted
end

-- 检查是否为错误对象
-- @param obj 要检查的对象
function Errors:is_error(obj)
    return type(obj) == "table" and obj.type and obj.message and obj.timestamp
end

-- 错误上下文信息收集器
local ErrorContext = {
    -- 全局上下文信息
    global_context = {},

    -- 上下文信息类型
    context_types = {
        BATTLE_ID = "battle_id",
        CHARACTER_ID = "character_id",
        SKILL_ID = "skill_id",
        ITEM_ID = "item_id",
        MODULE = "module",
        FUNCTION = "function",
        LINE_NUMBER = "line_number",
        OPERATION = "operation",
        USER_ACTION = "user_action",
        SYSTEM_STATE = "system_state",
        PERFORMANCE_DATA = "performance_data"
    }
}

-- 设置全局上下文信息
-- @param context_type 上下文类型
-- @param value 上下文值
function ErrorContext.set_global_context(context_type, value)
    ErrorContext.global_context[context_type] = value
end

-- 获取全局上下文信息
-- @param context_type 上下文类型（可选）
-- @return 上下文值或整个上下文表
function ErrorContext.get_global_context(context_type)
    if context_type then
        return ErrorContext.global_context[context_type]
    end
    return ErrorContext.global_context
end

-- 清除全局上下文信息
-- @param context_type 要清除的上下文类型（可选，不提供则清除所有）
function ErrorContext.clear_global_context(context_type)
    if context_type then
        ErrorContext.global_context[context_type] = nil
    else
        ErrorContext.global_context = {}
    end
end

-- 收集错误上下文信息
-- @param error_context 错误特定的上下文（可选）
-- @return 完整的上下文信息
function ErrorContext.collect_context(error_context)
    local context = {}

    -- 复制全局上下文
    for key, value in pairs(ErrorContext.global_context) do
        context[key] = value
    end

    -- 添加错误特定上下文
    if error_context then
        for key, value in pairs(error_context) do
            context[key] = value
        end
    end

    -- 添加系统信息
    context.system_info = {
        timestamp = os.time(),
        date = os.date("%Y-%m-%d %H:%M:%S"),
        memory_usage = collectgarbage("count"),
        lua_version = _VERSION
    }

    return context
end

-- 创建带上下文的错误对象
-- @param error_type 错误类型
-- @param message 错误信息
-- @param details 错误详情（可选）
-- @param error_context 错误上下文（可选）
function Errors:create_with_context(error_type, message, details, error_context)
    local error_obj = self:create(error_type, message, details)

    -- 收集上下文信息
    error_obj.context = ErrorContext.collect_context(error_context)

    return error_obj
end

-- 获取错误上下文摘要
-- @param error_obj 错误对象
-- @return 上下文摘要字符串
function Errors:get_context_summary(error_obj)
    if not error_obj.context then
        return "无上下文信息"
    end

    local summary_parts = {}

    -- 按优先级添加重要的上下文信息
    local priority_order = {
        "battle_id", "character_id", "skill_id", "item_id",
        "module", "function", "operation", "user_action"
    }

    for _, key in ipairs(priority_order) do
        if error_obj.context[key] then
            table.insert(summary_parts, string.format("%s:%s", key, tostring(error_obj.context[key])))
        end
    end

    if #summary_parts == 0 then
        return "无关键上下文信息"
    end

    return table.concat(summary_parts, " | ")
end

-- 格式化带上下文的错误信息
-- @param error_obj 错误对象
function Errors:format_with_context(error_obj)
    local formatted = self:format(error_obj)

    if error_obj.context then
        local context_summary = self:get_context_summary(error_obj)
        if context_summary ~= "无关键上下文信息" then
            formatted = formatted .. "\n上下文: " .. context_summary
        end
    end

    return formatted
end

-- 错误上下文管理器（便于在不同模块中使用）
local ContextManager = {}

-- 设置战斗上下文
-- @param battle_id 战斗ID
function ContextManager.set_battle_context(battle_id)
    ErrorContext.set_global_context("battle_id", battle_id)
end

-- 设置角色上下文
-- @param character_id 角色ID
function ContextManager.set_character_context(character_id)
    ErrorContext.set_global_context("character_id", character_id)
end

-- 设置技能上下文
-- @param skill_id 技能ID
function ContextManager.set_skill_context(skill_id)
    ErrorContext.set_global_context("skill_id", skill_id)
end

-- 设置模块上下文
-- @param module_name 模块名称
function ContextManager.set_module_context(module_name)
    ErrorContext.set_global_context("module", module_name)
end

-- 设置操作上下文
-- @param operation 操作名称
function ContextManager.set_operation_context(operation)
    ErrorContext.set_global_context("operation", operation)
end

-- 设置性能数据上下文
-- @param performance_data 性能数据表
function ContextManager.set_performance_context(performance_data)
    ErrorContext.set_global_context("performance_data", performance_data)
end

-- 执行函数并自动收集上下文
-- @param func 要执行的函数
-- @param context 执行上下文（可选）
-- @param ... 函数参数
function Errors:execute_with_context(func, context, ...)
    if context then
        ErrorContext.set_global_context("operation", context.operation or "unknown_operation")
        ErrorContext.set_global_context("function", context.function_name or "unknown_function")
        ErrorContext.set_global_context("line_number", context.line_number)
    end

    local success, result = pcall(func, ...)

    if not success then
        -- 如果出错，创建带上下文的错误对象
        local error_obj = self:create_with_context("SYSTEM_ERROR", result, nil, context)
        return false, error_obj
    end

    return true, result
end

-- 导出到Errors模块
Errors.ErrorContext = ErrorContext
Errors.ContextManager = ContextManager

-- 导出错误类型常量
for type_name, type_value in pairs(Errors.types) do
    Errors[type_name] = type_value
end

-- 导出模块
return Errors
